/* Copyright 2001,2002,2003 NAH6
 * All Rights Reserved
 *
 * Parts Copyright DoD, Parts Copyright Starium
 *
 */
/*LINTLIBRARY*/
/*PROTOLIB1*/
/*#include <math.h>*/
#include "main.h"
#include "scb_code.h"

/**************************************************************************
*
* ROUTINE
*               SCBGainEncode
*
* FUNCTION
*
*               encode and quantize code book gain
*
* SYNOPSIS
*               SCBGainEncode(UGain, QGain)
*
*   formal
*
*                       data    I/O
*       name            type    type    function
*       -------------------------------------------------------------------
*       UGain           fxpt_16 i       code book gain input (true value)
*       QGain           int     o       encoded code book gain ZERO BASED index
*
*       SCBGainEncode   fxpt_16 func    encoded code book gain
*
***************************************************************************
*
* DESCRIPTION
**
*      Fast code book gain quantizer to allow practical quantization
*      inside the code book search loop. A binary tree search quantization
*      is implemented below.
*
**************************************************************************/

/* *Log quantization                               */

/* Converted from float to fixed-point format (11.4) (multiply by 16) */
static fxpt_16 SCBGainTable[32] =
{
-21280, -13920, -10560,  -8320,  -6688,  -5440,  -4448,  -3584,
 -2848,  -2176,  -1568,  -1024,   -560,   -208,    -48,    -16,
    16,     48,    208,    560,   1024,   1568,   2176,   2848,
  3584,   4448,   5440,   6688,   8320,  10560,  13920,  21280
};

fxpt_16 SCBGainEncode(fxpt_16 UGain, int *QGain)
{
        int i;
        /* Converted from float to fixed-point format (11.4) (mult by 16) */
        static fxpt_16 midpoints[31] =
        {
                -17600, -12240,  -9440,  -7504,  -6064,  -4944,  -4016,  -3216,
                 -2512,  -1872,  -1296,   -792,   -384,   -128,    -32,      0,
                    32,    128,    384,    792,   1296,   1872,   2512,   3216,
                  4016,   4944,   6064,   7504,   9440,  12240,  17600
        };

        /* Binary tree search for closest gain                           */
        for (*QGain = 15, i = 8; i >= 1; i = i >> 1) {
                if (UGain > midpoints[*QGain])
                        *QGain += i;
                else
                        *QGain -= i;
        }
        if (UGain > midpoints[*QGain])
                (*QGain)++;

        /* Return quantized gain and ZERO based index                    */
        return (SCBGainTable[*QGain]);
}


/**************************************************************************
*
* ROUTINE
*               SCBGainDecode
*
* FUNCTION
*
*               decode code book gain from the quantized gain
*
* SYNOPSIS
*               SCBGainDecode(QGain, UGain)
*
*   formal
*
*                       data    I/O
*       name            type    type    function
*       -------------------------------------------------------------------
*       QGain           int     i       Quantized gain
*       UGain           fxpt_16 o       Unquantized gain
*
***************************************************************************
*
* REFERENCES
*
*       Quantizing for Minimum Distorion
*       J. Max
*       IRE Trans. Inform. Theory, vol. IT-6, pp.7-12, Mar. 1960
*
***************************************************************************
*
*       The data used in the table generation is from 3m3f.spd.
*
**************************************************************************/
void SCBGainDecode(int QGain, fxpt_16 *UGain)

{
        /* Choose appropriate gain */
        *UGain = SCBGainTable[QGain];
}
